﻿////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// <copyright>Copyright 2008-2011 Andreas Huber Doenni</copyright>
// Distributed under the Microsoft Public License (Ms-PL).
// See accompanying file License.txt or copy at http://mews.codeplex.com/license.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace Mews.Mime
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.IO;

    /// <summary>Represents an unstructured header field (see <a href="http://www.ietf.org/rfc/rfc5322.txt">RFC 5322</a>
    /// 2.2.1.).</summary>
    /// <threadsafety static="true" instance="false"/>
    public sealed class UnstructuredHeaderField : HeaderField<UnstructuredHeaderField>
    {
        private string body = string.Empty;

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>Initializes a new instance of the <see cref="UnstructuredHeaderField"/> class.</summary>
        /// <param name="name">The name of the header field, usually one of the <see cref="HeaderFieldNames"/> members
        /// or a name starting with "X-".</param>
        /// <exception cref="ArgumentException"><paramref name="name"/> is <c>null</c> or empty.</exception>
        public UnstructuredHeaderField(string name) : base(name)
        {
        }

        /// <summary>Gets or sets the body of the header field.</summary>
        /// <exception cref="ArgumentNullException">Attempted to set to <c>null</c>.</exception>
        /// <remarks>The default value is <see cref="string.Empty"/>, which is set during construction and when the
        /// parser does not find a valid body.</remarks>
        public string Body
        {
            get
            {
                return this.body;
            }

            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }

                this.body = value;
            }
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        internal sealed override void WriteTo(Stream stream)
        {
            HeaderFieldHelper.FoldHeaderField(
                this.Name, new[] { new HeaderFieldBodyPart(this.body, CanContainEncodedWords(this.Name)) }, stream);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private static bool CanContainEncodedWords(string name)
        {
            var uppercaseName = name.ToUpper(CultureInfo.InvariantCulture);

            switch (uppercaseName)
            {
                case UppercaseHeaderFieldNames.Subject:
                case UppercaseHeaderFieldNames.Comments:
                case UppercaseHeaderFieldNames.Keywords:
                    return true;
                default:
                    return uppercaseName.StartsWith("X-", StringComparison.Ordinal);
            }
        }
    }
}
